extern crate pest;
extern crate rustyline;

#[macro_use]
extern crate pest_derive;

use pest::Parser;
use rustyline::error::ReadlineError;
use rustyline::Editor;


// Tell Rust, that the struct below shall be created from the grammar
// in the referenced file.
#[derive(Parser)]
#[grammar = "grammar.pest"]
pub struct PitPotRespiteParser;


const HISTORY_FILENAME: &str = "history.txt";
const PROMPT: &str = "LISPY>> ";


fn print_initial_info() {
    println!("Lispy Version 0.0.1");
    println!("Press Ctrl+c to Exit.\n");
}


fn repl(mut readline_editor: Editor<()>) {
    loop {
        let readline = readline_editor.readline(PROMPT);
        match readline {
            Ok(line) => {
                readline_editor.add_history_entry(line.as_ref());
                match PitPotRespiteParser::parse(Rule::combination, &line) {
                    Ok(parsing_result) => {
                        println!("Parsing OK: {}", parsing_result);
                    },
                    Err(some_err) => {
                        println!("There was an error while parsing: {:#?}", some_err);
                    }
                }
            },
            Err(ReadlineError::Interrupted) => {
                println!("CTRL-C");
                break
            },
            Err(ReadlineError::Eof) => {
                println!("CTRL-D");
                break
            },
            Err(err) => {
                println!("Error: {:?}", err);
                break
            }
        }
        readline_editor
            .save_history(HISTORY_FILENAME)
            .expect("Could not save to readline history.");
    }
}


fn main() {
    // We create an editor for the readline history.
    let mut readline_editor = Editor::<()>::new();
    // And then load the history, if it exists.
    if readline_editor.load_history(HISTORY_FILENAME).is_err() {
        println!("No previous history.");
    }
    print_initial_info();
    repl(readline_editor);
}
